package cn.wenhaha.common.utils;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.JarClassLoader;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.MD5;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 * 插件类加载器
 * --------
 *
 * @author ：wyndem
 * @Date ：Created in 2022-07-10 13:54
 */
public class PluginsClassLoaderUtil {


    private final   static Map<String,JarClassLoader> classLoaders=new HashMap<>();

    public static synchronized JarClassLoader addClassJar(File classJar,String key){
        JarClassLoader load = JarClassLoader.load(classJar);
       if(StrUtil.isEmpty(key)){
           key=getKey(classJar);
       }
       if(classLoaders.containsKey(key)){
           IoUtil.close(classLoaders.get(key));
       }
        classLoaders.put(key, load);
       return load;
    }

    public  static boolean isLoader(String key){
        return StrUtil.isEmpty(key) ? false : classLoaders.containsKey(key);
    }

    public static JarClassLoader getJarClassLoader(String key){
        if(StrUtil.isEmpty(key)) return  null;
        if(!classLoaders.containsKey(key)) return null;
        return classLoaders.get(key);
    }

    public static String getKey(File classJar){
        return MD5.create().digestHex(classJar.getPath());
    }


    public static synchronized void unloadClassJar(String key){
        if(StrUtil.isNotEmpty(key) && classLoaders.containsKey(key)){
            IoUtil.close(classLoaders.remove(key));
            System.gc();
        }
    }


    public static <T> T  getObject(String className, JarClassLoader classLoader,Class<?> clazz) {
        try {
            Class<?> aClass = classLoader.loadClass(className);
            if (clazz.isAssignableFrom(aClass)){
                return  (T)aClass.newInstance();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return null;
    }


}
